package com.jkdz.spyke.widgetUIs {
	import flash.external.ExternalInterface;
	import spark.components.Button;
	import spark.components.Form;
	import spark.components.FormItem;
	import spark.components.Group;
	import spark.components.HGroup;
	import spark.components.HSlider;
	import spark.components.VGroup;
	import spark.layouts.HorizontalAlign;
	import spark.layouts.VerticalAlign;
	import spark.layouts.VerticalLayout;

	import com.jkdz.spyke.flexUI.helpers.Link;
	import com.jkdz.spyke.flexUI.helpers.SuperWindow;
	import com.jkdz.spyke.flexUI.main.Main;
	import com.jkdz.spyke.rs.PaintSettings;
	import com.jkdz.spyke.rs.SpykePaint;
	import com.jkdz.spyke.rs.SpykePaintListener;

	import mx.containers.Canvas;
	import mx.controls.ColorPicker;
	import mx.controls.TextInput;
	import mx.core.FlexGlobals;
	import mx.events.ColorPickerEvent;

	import flash.display.BlendMode;
	import flash.display.Shape;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	
	public class SpykePaintUI extends SpykeWidgetUI implements SpykePaintListener {
		
		private var widget:SpykePaint;
		private var window:SuperWindow;
		private var canvas:Canvas;
		
		public function SpykePaintUI(widget:SpykePaint) {
			this.widget = widget;
		}
		
		override public function display(onComplete:Function):void {
			
			widget.getPaintSettings(function(ret:PaintSettings):void {
				showUI(ret, onComplete);
			});
		}
		
		public function unPublished():void {
			if (window.isVisible()) {
				window.close();
			}
		}
		
		private function showUI(settings:PaintSettings, onComplete:Function):void {
			
			var drawing:int = 0;
			canvas = new Canvas();
			canvas.width = settings.w;
			canvas.height = settings.h;
			
			var drawStartX:int = 0;
			var drawStartY:int = 0;
			
			canvas.addEventListener(MouseEvent.MOUSE_DOWN, function(e:MouseEvent):void {
				drawing = 1;
				
				drawStartX = e.localX;
				drawStartY = e.localY;
				//canvas.graphics.moveTo(e.localX, e.localY);
			});
			canvas.addEventListener(MouseEvent.MOUSE_MOVE, function(e:MouseEvent):void {
				if (drawing > 0 && window.isStable()) {
					drawing = 2;
					
					var startHash:int = drawStartX*10000+drawStartY;
					var stopHash:int = e.localX*10000+e.localY;
					var alphaBroadHash:int = ((int)(alphaPicker.value*100))*10000 + (int)(10*Math.pow(brushPicker.value, 2));
					widget.drawNewLine(startHash, stopHash, colorPicker.selectedColor, alphaBroadHash);
					drawStartX = e.localX;
					drawStartY = e.localY;
					//canvas.graphics.lineTo(e.localX, e.localY);
				}
				brushPreview.x = e.localX;
				brushPreview.y = e.localY;
			});
			canvas.addEventListener(MouseEvent.MOUSE_UP, function(e:MouseEvent):void {
				if (drawing == 1) {
					//canvas.graphics.lineStyle(0, 0xfffffffe, 0.0);
					//canvas.graphics.beginFill(colorPicker.selectedColor, alphaPicker.value);
					//canvas.graphics.drawCircle(e.localX, e.localY, Math.pow(brushPicker.value, 2)/2);
					//canvas.graphics.endFill();
					//canvas.graphics.lineStyle(Math.pow(brushPicker.value, 2), colorPicker.selectedColor, alphaPicker.value);
					var startHash:int = drawStartX*10000+drawStartY;
					var stopHash:int = e.localX*10000+e.localY;
					var alphaBroadHash:int = ((int)(alphaPicker.value*100))*10000 + (int)(10*Math.pow(brushPicker.value, 2));
					widget.drawNewLine(startHash, stopHash, colorPicker.selectedColor, alphaBroadHash);
					drawStartX = e.localX;
					drawStartY = e.localY;
				}
				drawing = 0;
			});
			canvas.addEventListener(MouseEvent.MOUSE_OVER, function(e:MouseEvent):void {
				if (e.buttonDown) {
					
					drawStartX = e.localX;
					drawStartY = e.localY;
					//canvas.graphics.moveTo(e.localX, e.localY);
					
					drawing = 2;
				}
				brushPreview.visible = true;
				cursorManager.setCursor(Shape);
			});
			canvas.addEventListener(MouseEvent.MOUSE_OUT, function(e:MouseEvent):void {
				drawing = 0;
				brushPreview.visible = false;
				cursorManager.removeAllCursors();
			});
			canvas.graphics.beginFill(settings.bgColor && 0x00ffffff == 0x00ffffff ? 0xfffffffe:settings.bgColor);
			canvas.graphics.drawRect(0, 0, canvas.width, canvas.height);
			canvas.graphics.endFill();

			var brushPreview:Canvas = new Canvas();
			brushPreview.visible = false;
			brushPreview.mouseEnabled = false;
			brushPreview.mouseChildren = false;
			brushPreview.blendMode = BlendMode.INVERT;
			canvas.addElement(brushPreview);
			
			var vg:VGroup = new VGroup();
			vg.paddingBottom = vg.paddingLeft = vg.paddingRight = vg.paddingTop = vg.gap = 0;
			
			var masker:Canvas = new Canvas();
			masker.graphics.beginFill(0xff000000);
			masker.graphics.drawRect(0, 0, canvas.width, canvas.height);
			masker.graphics.endFill();
			canvas.mask = masker;
			vg.addElement(masker);
			vg.addElement(canvas);
			var line:Canvas = new Canvas();
			line.width = canvas.width;
			line.height = 1;
			line.graphics.beginFill(0xff000000);
			line.graphics.drawRect(0, 0, line.width, line.height);
			vg.addElement(line);
			
			var hg:HGroup = new HGroup();
			hg.paddingBottom = hg.paddingLeft = hg.paddingRight = hg.paddingTop = 0;
			hg.gap = 10;
			hg.verticalAlign = VerticalAlign.MIDDLE;
			vg.addElement(hg);
			
			var colorPicker:ColorPicker = new ColorPicker();
			hg.addElement(colorPicker);
			colorPicker.addEventListener(ColorPickerEvent.CHANGE, function(e:ColorPickerEvent):void {
				//canvas.graphics.lineStyle(Math.pow(brushPicker.value, 2), colorPicker.selectedColor, alphaPicker.value);
				brushPreview.graphics.clear();
				brushPreview.graphics.beginFill(colorPicker.selectedColor, alphaPicker.value);
				brushPreview.graphics.drawCircle(0, 0, Math.pow(brushPicker.value, 2)/2);
				brushPreview.graphics.endFill();
			});
			
			var brushPicker:HSlider = new HSlider();
			brushPicker.stepSize = 0.1;
			brushPicker.minimum = 1.0;
			brushPicker.maximum = 10.0;
			brushPicker.value = 2.0;
			brushPicker.width = (canvas.width-72-2*hg.gap)/2;
			brushPicker.dataTipFormatFunction = function(d:Object):String {
				return "Brush size: "+Math.floor(10*Math.pow((Number)(d), 2))/10.0;
			};
			hg.addElement(brushPicker);
			brushPicker.addEventListener(Event.CHANGE, function(e:Event):void {
				//canvas.graphics.lineStyle(Math.pow(brushPicker.value, 2), colorPicker.selectedColor, alphaPicker.value);
				brushPicker.thumb.scaleX = brushPicker.thumb.scaleY = Math.pow(Math.pow(brushPicker.value, 2), 0.15);
				brushPreview.graphics.clear();
				brushPreview.graphics.beginFill(colorPicker.selectedColor, alphaPicker.value);
				brushPreview.graphics.drawCircle(0, 0, Math.pow(brushPicker.value, 2)/2);
				brushPreview.graphics.endFill();
			});
			
			var alphaPicker:HSlider = new HSlider();
			alphaPicker.stepSize = 0.01;
			alphaPicker.minimum = 0.01;
			alphaPicker.maximum = 1.0;
			alphaPicker.value = 1.0;
			alphaPicker.width = brushPicker.width;
			alphaPicker.dataTipFormatFunction = function(d:Object):String {
				return "Brush alpha: "+d;
			};
			hg.addElement(alphaPicker);
			alphaPicker.addEventListener(Event.CHANGE, function(e:Event):void {
				//canvas.graphics.lineStyle(Math.pow(brushPicker.value, 2), colorPicker.selectedColor, alphaPicker.value);
				alphaPicker.alpha = 0.2 + alphaPicker.value*0.8;
				brushPreview.graphics.clear();
				brushPreview.graphics.beginFill(colorPicker.selectedColor, alphaPicker.value);
				brushPreview.graphics.drawCircle(0, 0, Math.pow(brushPicker.value, 2)/2);
				brushPreview.graphics.endFill();
			});
			
			var clearLink:Link = new Link("Reset");
			hg.addElement(clearLink);
			clearLink.addEventListener(MouseEvent.CLICK, function(e:MouseEvent):void {
				showChangeSettingsDialog();
			});

			//canvas.graphics.lineStyle(Math.pow(brushPicker.value, 2), colorPicker.selectedColor, alphaPicker.value);
			brushPicker.thumb.scaleX = brushPicker.thumb.scaleY = Math.pow(Math.pow(brushPicker.value, 2), 0.2);
			alphaPicker.alpha = 0.2 + alphaPicker.value*0.8;
			brushPreview.graphics.clear();
			brushPreview.graphics.beginFill(colorPicker.selectedColor, alphaPicker.value);
			brushPreview.graphics.drawCircle(0, 0, Math.pow(brushPicker.value, 2)/2);
			brushPreview.graphics.endFill();
			
			this.addElement(vg);
			
			this.window = SuperWindow.display(FlexGlobals.topLevelApplication as Main, this, settings.name, false, true, true, false, new Point(Math.random()*((FlexGlobals.topLevelApplication as Main).width-canvas.width), Math.random()*((FlexGlobals.topLevelApplication as Main).height-canvas.height)), onClose);
			
			widget.registerListener(this);
			
			onComplete();
		}
		
		private function onClose():void {
			widget.unPublish();
		}
		
		private function showChangeSettingsDialog():void {
			var crfg:Group = new Group();
			var vl:VerticalLayout = new VerticalLayout();
			vl.horizontalAlign = HorizontalAlign.CENTER;
			vl.paddingBottom = 10.0;
			crfg.layout = vl;
			var crff:Form = new Form();
			var crffi:FormItem = new FormItem();
			var crfti:TextInput = new TextInput();
			var crfb:Button = new Button();
			crfb.label = "OK";
			var submit:Function = function():void {
				if (crfti.text.length == 0) {
					SuperWindow.alert(FlexGlobals.topLevelApplication as Main, "Wrong name", "The name cannot be empty.", function():void {
						cnw.close();
					});
				} else {
					widget.resetPaint(new PaintSettings()); // ?
					cnw.close();
				}
			};
			crfb.addEventListener(MouseEvent.CLICK, function(e:MouseEvent):void {
				submit();
			});
			crffi.label = "Paint name:";
			crffi.addElement(crfti);
			crff.addElement(crffi);
			crfti.text = window.title;
			crfti.addEventListener(KeyboardEvent.KEY_DOWN, function(e:KeyboardEvent):void {
				if (e.charCode == 13) {
					submit();
				}
			});
			crfg.addElement(crff);
			crfg.addElement(crfb);
			var cnw:SuperWindow = SuperWindow.display((Main)(FlexGlobals.topLevelApplication), crfg, "SpykePaint settings", true, true, true, false);
			focusManager.setFocus(crfti);
		}

		public function paintReset(a:PaintSettings):void {
			//apply new canvas size
			canvas.graphics.clear();
			canvas.graphics.beginFill(a.bgColor && 0x00ffffff == 0x00ffffff ? 0xfffffffe:a.bgColor);
			canvas.graphics.drawRect(0, 0, canvas.width, canvas.height);
			canvas.graphics.endFill();
		}

		public function newLineDrawn(startHash:int, stopHash:int, col:int, alphaBroadHash:int):void {
			var stax:int = startHash / 10000;
			var stay:int = startHash % 10000;
			var stox:int = stopHash / 10000;
			var stoy:int = stopHash % 10000;
			var a:Number = ((int)(alphaBroadHash / 10000))/100.0;
			var b:Number = ((int)(alphaBroadHash % 10000))/10.0;
			
			if (stax == stox && stay == stoy) {
				canvas.graphics.lineStyle(0, 0xfffffffe, 0.0);
				canvas.graphics.beginFill(col, a);
				canvas.graphics.drawCircle(stax, stay, b/2.0);
				canvas.graphics.endFill();
				ExternalInterface.call("alert", "problem");
			} else {
				canvas.graphics.lineStyle(b, col, a);
				canvas.graphics.moveTo(stax, stay);
				canvas.graphics.lineTo(stox, stoy);
			}
		}

	}
}